<?php

namespace App\Common\Http;


use App\Exception\BusinessException;
use Hyperf\HttpMessage\Cookie\Cookie;
use Hyperf\HttpMessage\Exception\HttpException;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Utils\Context;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;

class Response
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var ResponseInterface
     */
    protected $response;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        try {
            $this->response = $container->get(ResponseInterface::class);
        } catch (NotFoundExceptionInterface | ContainerExceptionInterface $e) {
            throw new BusinessException($e->getCode(), $e->getMessage());
        }
    }

    public function success($data = [], $message = 'success'): PsrResponseInterface
    {
        return $this->response->json([
            'code' =>200,
            'message' => $message,
            'data' => $data
        ]);
    }

    public function fail($code, $message = 'failure', $data = []): PsrResponseInterface
    {
        return  $this->response->json([
           'code' => $code,
           'message' => $message,
           'data' => $data
        ]);
    }

    public function redirect($url, $status = 302): PsrResponseInterface
    {
        return $this->response()
            ->withAddedHeader('Location', (string) $url)
            ->withStatus($status);
    }

    public function cookie(Cookie $cookie): Response
    {
        $response = $this->response()->withCookie($cookie);
        Context::set(PsrResponseInterface::class, $response);
        return $this;
    }

    public function handleException(HttpException $throwable): PsrResponseInterface
    {
        return $this->response()
            ->withAddedHeader('Server', 'Hyperf')
            ->withStatus($throwable->getStatusCode())
            ->withBody(new SwooleStream($throwable->getMessage()));
    }

    public function response(): PsrResponseInterface
    {
        return Context::get(PsrResponseInterface::class);
    }
}